package ThreadingSafety;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 *  手动实现 线程池.
 *      一个线程池中 可以提交N个任务, 对应的线程池中有M个线程来负责完成这N个任务.
 *      如何把N个任务，分配给M个线程呢？ 生产者消费者模型，正好可以解决这个问题！
 *      先搞一个阻塞队列,每个被提交的任务，都被放到阻塞队列中.搞M个线程来取队列元素.
 *      如果队列空了,M个线程自然阻塞等待, 如果队列不为空,每个线程都取任务,执行任务,再来取下一个..直到队列空,线程继续阻塞~~
 */

class MyThreadPool {
    final private BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();

    public void submit(Runnable runnable) throws InterruptedException {
        // 添加任务的函数.
        queue.put(runnable);
    }

    public MyThreadPool(int m) {
        // 在构造方法中添加M个线程.负责完成工作
        for(int i = 0; i < m; ++i) {
            Thread t = new Thread(() -> {
                while(true) {
                    try {
                        Runnable runnable = queue.take();
                        runnable.run();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            t.start();
        }
    }
}

public class TestDemo25 {
    public static void main(String[] args) throws InterruptedException {
        MyThreadPool myThreadPool = new MyThreadPool(10);
        for (int i = 0; i < 1000; ++i) {
            int k = i;
            myThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println("当前执行任务: " + k + "  当前线程: " + Thread.currentThread().getName());
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });

        }
    }

}
